package com.mentalhealth.diary.common;

import io.jsonwebtoken.*;
import io.jsonwebtoken.security.Keys;
import org.springframework.util.StringUtils;

import javax.crypto.SecretKey;
import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * JWT工具类
 * 用于生成、解析和验证JWT令牌
 */
public class JwtUtil {

    /**
     * 密钥
     * 实际应用中建议从配置文件读取
     */
    private static final String SECRET_KEY = "mental-health-diary-secret-key-2025";
    
    /**
     * 过期时间（毫秒）
     * 7天 = 7 * 24 * 60 * 60 * 1000
     */
    private static final long EXPIRATION_TIME = 7 * 24 * 60 * 60 * 1000;
    
    /**
     * 获取签名密钥
     * @return SecretKey
     */
    private static SecretKey getSecretKey() {
        // 使用密钥生成安全密钥
        return Keys.hmacShaKeyFor(SECRET_KEY.getBytes(StandardCharsets.UTF_8));
    }
    
    /**
     * 生成JWT令牌
     * @param userId 用户ID
     * @return JWT令牌
     */
    public static String generateToken(Long userId) {
        // 设置JWT声明
        Map<String, Object> claims = new HashMap<>();
        claims.put("user_id", userId);
        
        // 生成令牌
        return Jwts.builder()
                // 设置声明
                .setClaims(claims)
                // 设置签发时间
                .setIssuedAt(new Date())
                // 设置过期时间
                .setExpiration(new Date(System.currentTimeMillis() + EXPIRATION_TIME))
                // 设置签名算法和密钥
                .signWith(getSecretKey(), SignatureAlgorithm.HS256)
                // 紧凑序列化
                .compact();
    }
    
    /**
     * 从JWT令牌中解析用户ID
     * @param token JWT令牌
     * @return 用户ID
     */
    public static Long getUserIdFromToken(String token) {
        if (!StringUtils.hasText(token)) {
            throw new BusinessException(401, "请先登录哦～");
        }
        
        try {
            // 解析令牌
            Claims claims = Jwts.parserBuilder()
                    .setSigningKey(getSecretKey())
                    .build()
                    .parseClaimsJws(token)
                    .getBody();
            
            // 获取用户ID
            return claims.get("user_id", Long.class);
        } catch (ExpiredJwtException e) {
            // 令牌过期
            throw new BusinessException(401, "登录已失效，请重新登录～");
        } catch (JwtException e) {
            // 令牌无效
            throw new BusinessException(401, "请先登录哦～");
        }
    }
    
    /**
     * 验证JWT令牌是否有效
     * @param token JWT令牌
     * @return 是否有效
     */
    public static boolean validateToken(String token) {
        if (!StringUtils.hasText(token)) {
            return false;
        }
        
        try {
            // 解析令牌
            Jwts.parserBuilder()
                    .setSigningKey(getSecretKey())
                    .build()
                    .parseClaimsJws(token);
            return true;
        } catch (JwtException e) {
            // 令牌无效
            return false;
        }
    }
    
    /**
     * 从Bearer令牌中提取JWT
     * @param bearerToken Bearer令牌
     * @return JWT令牌
     */
    public static String extractTokenFromBearer(String bearerToken) {
        if (!StringUtils.hasText(bearerToken) || !bearerToken.startsWith("Bearer ")) {
            return null;
        }
        return bearerToken.substring(7);
    }
}